package ar.com.spsolutions.splibrary.services;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.springframework.security.access.annotation.Secured;
import org.springframework.transaction.annotation.Transactional;

import ar.com.spsolutions.splibrary.author.Author;
import ar.com.spsolutions.splibrary.book.Book;
import ar.com.spsolutions.splibrary.book.BookCopy;
import ar.com.spsolutions.splibrary.book.LoanBook;
import ar.com.spsolutions.splibrary.book.category.Category;
import ar.com.spsolutions.splibrary.general.RoleConverterService;
import ar.com.spsolutions.splibrary.user.User;

@Transactional
public class LibraryServiceFacade implements Serializable {
	private static final long serialVersionUID = -4940422056856980245L;
	private EntityService entityService;

	public EntityService getEntityService() {
		return this.entityService;
	}

	public void setEntityService(final EntityService entityService) {
		this.entityService = entityService;
	}

	@Secured(RoleConverterService.ROLE_GUEST)
	public void add(final User example) {
		this.getUserService().add(example);
	}

	private UserService getUserService() {
		return this.getEntityService().getUserService();
	}

	public void update(final User user) {
		this.getUserService().update(user);
	}

	public void delete(final User user) {
		this.getUserService().deleted(user);
	}

	public void update(final Category category) {
		this.getCategoryService().update(category);
	}

	private CategoryService getCategoryService() {
		return this.getEntityService().getCategoryService();
	}

	public void deleted(final Category category) {
		this.getCategoryService().deleted(category);
	}

	@Secured(RoleConverterService.ROLE_LIBRARIAN)
	public void add(final Category category) {
		this.getCategoryService().add(category);
	}

	@Secured(RoleConverterService.ROLE_LIBRARIAN)
	public void add(final Author author) {
		this.getAuthorService().add(author);
	}

	private AuthorService getAuthorService() {
		return this.getEntityService().getAuthorService();
	}

	public void deleted(final Author author) {
		this.getAuthorService().deleted(author);
	}

	public void update(final Author author) {
		this.getAuthorService().update(author);
	}

	@Secured(RoleConverterService.ROLE_LIBRARIAN)
	public void add(final Book book) {
		this.getBookService().add(book);
	}

	private BookService getBookService() {
		return this.getEntityService().getBookService();
	}

	public Author attachSession(final Author author) {
		return this.getAuthorService().attachSession(author);
	}

	public Book attachSession(final Book book) {
		return this.getBookService().attachSession(book);
	}

	public Book update(final Book book) {
		return (Book) this.getBookService().update(book);

	}

	public void deleted(final Book book) {
		this.getBookService().deleted(book);
	}

	public List<Book> findByTitleLike(final String title) {
		return this.getBookService().findByTitleLike(title);
	}

	public List<Book> findByISBN(final String isbn) {
		final List<Book> res = new ArrayList<Book>();
		res.add(this.getBookService().findByISBN(isbn));
		return res;
	}

	public List<Author> findAllAuthors() {
		return this.getAuthorService().findAll();
	}

	public List<Book> findByAuthor(final Author author) {
		return this.getBookService().findByAuthor(author);
	}

	public List<Book> findByTitle(final String title) {
		final List<Book> res = new ArrayList<Book>();
		final Book book = this.getBookService().findByName(title);
		if (book != null) {
			res.add(book);
		}
		return res;
	}

	public List<Book> findByISBNLike(final String isbn) {
		return this.getBookService().findByISBNLike(isbn);
	}

	@Transactional
	public void createLoanFor(final User user, final Book book) {
		this.get(book).loanTo(this.get(user));
	}

	public Book get(final Book book) {
		return this.getBookService().get(book);
	}

	public User get(final User user) {
		return this.getUserService().get(user);
	}

	private LoanBookService getLoanBookService() {
		return this.getEntityService().getLoanBookService();
	}

	public List<LoanBook> allLoanForUser(final User user) {
		return this.getUserService().getAllLoansFor(user);
	}

	@Transactional
	public String titleFor(final BookCopy copy) {
		final Book book = copy.getBook();
		this.attachSession(book);
		return book.getTitle();
	}

	@Transactional
	public String expirationDate(final LoanBook loan) {
		return this.getLoanBookService().getExpirationDate(loan)
				.toString("dd/MM/yyyy");
	}

	public void attachSession(final LoanBook loan) {
		this.getLoanBookService().attachSession(loan);
	}

	public void update(final LoanBook loan) {
		this.getLoanBookService().update(loan);
	}

	@Transactional()
	public void refun(final LoanBook loan) {
		loan.refun();
		this.getLoanBookService().update(loan);
	}

	public LoanBook get(final LoanBook loan) {
		return this.getLoanBookService().get(loan);

	}

	public void delete(final Book book) {
		this.getBookService().deleted(book);
	}

	public Author get(final Author author) {
		return this.getAuthorService().get(author);
	}

	public List<Book> findByCategory(final Category category) {
		return this.getCategoryService().getBooksFor(category);
	}

	public List<Category> findAllCategories() {
		return this.getCategoryService().findAll();
	}

}
